/**
 * 
 */
package pe.bf.extranet.dao.impl;

import java.math.BigInteger;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import oracle.jdbc.OracleTypes;

import org.apache.log4j.Logger;

import pe.bf.base.dao.impl.BaseDAOImpl;
import pe.bf.base.types.OutParameter;
import pe.bf.domain.bean.Abono;
import pe.bf.domain.bean.Empresa;
import pe.bf.domain.bean.SolicitudAbono;
import pe.bf.domain.bean.Transferencia;
import pe.bf.domain.exceptions.DomainException;
import pe.bf.extranet.dao.SolicitudAbonoDAO;

/**
 *  
 * 
 */
public class SolicitudAbonoDAOImpl extends BaseDAOImpl implements
		SolicitudAbonoDAO {

	Logger logger = Logger.getLogger(SolicitudAbonoDAOImpl.class);

	static final String USP_CRE_SOLIC_ABONO = "{call PGK_SOLICITUDABONO.USP_CRE_SOLIC_ABONO(?,?,?,?,?,?,?,?,?,?,?,?)}";
	static final String REG_TRANSFERENCIAS = "{call PGK_SOLICITUDABONO.REG_TRANSFERENCIAS(?,?)}";
	static final String USP_CRE_ABONO = "{call PGK_SOLICITUDABONO.USP_CRE_ABONO(?,?,?,?,?,?,?)}";
	static final String USP_ACT_SOLIC_ABONO = "{call PGK_SOLICITUDABONO.USP_ACT_SOLIC_ABONO(?,?,?)}";
	static final String USP_ELI_SOLIC_ABONO = "{call PGK_SOLICITUDABONO.USP_ELI_SOLIC_ABONO(?)}";
	static final String USP_LIS_SOLIC_ABONO = "{call PGK_SOLICITUDABONO.USP_LIS_SOLIC_ABONO(?)}";
	static final String USP_LIS_SOLIC_ABONO_EMPRESA = "{call PGK_SOLICITUDABONO.USP_LIS_SOLIC_ABONO_EMPRESA(?,?)}";
	static final String USP_LIS_DET_SOLIC_ABONO = "{call PGK_SOLICITUDABONO.USP_LIS_DET_SOLIC_ABONO(?,?,?)}";

	/**
	 * 
	 * @param dataSource
	 */
	public SolicitudAbonoDAOImpl(DataSource dataSource) {
		super(dataSource);
	}

	@SuppressWarnings({ "finally" })
	@Override
	public List<String> createSolicitudAbono(SolicitudAbono solicitudAbono)
			throws DomainException {
		List<String> errores = new ArrayList<String>();
		try {
			solicitudAbono.setIdSolicitudabono(invokeStoreProcedureGetAbono(
					USP_CRE_SOLIC_ABONO, solicitudAbono.getNombrearchivo(),
					solicitudAbono.getDescripcion(),
					solicitudAbono.getMoneda(), solicitudAbono.getMontototal(),
					solicitudAbono.getNroempleados(), solicitudAbono
							.getTotalempleados(),
					solicitudAbono.getTipoabono(), solicitudAbono
							.getUsuariocreacion(), solicitudAbono.getAdjunto()
							.getArchivo(), solicitudAbono.getEmpresa()
							.getIdEmpresa(), solicitudAbono
							.getFechacargaArchivo(), new OutParameter(
							OracleTypes.VARCHAR)));
			if (solicitudAbono.getIdSolicitudabono() != -1) {
				registrarTransferencias(solicitudAbono.getTransferencias(),
						solicitudAbono.getIdSolicitudabono());
			}
			errores = createDetalleSolicitudAbono(
					(List<Abono>) solicitudAbono.getAbonos(),
					solicitudAbono.getIdSolicitudabono());
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e, e.fillInStackTrace());
			errores.add("Error al grabar cabecera =" + e.getMessage());
			throw new DomainException(e);
		} finally {
			return errores;
		}

	}

	@Override
	public List<String> createDetalleSolicitudAbono(List<Abono> detalle, long id)
			throws DomainException {
		List<String> errores = new ArrayList<String>();

		if (id == -1) {
			return errores;
		}

		for (Abono abono : detalle) {
			try {
				invokeStoreProcedure(USP_CRE_ABONO, id, abono.getMoneda(),
						abono.getMonto(), abono.getNombres(),
						abono.getNrocuenta(), abono.getNrodocumento(),
						abono.getTipodocumento());

			} catch (Exception e) {
				errores.add("Abono " + abono.getNrocuenta() + " con error "
						+ e.getMessage());
				e.printStackTrace();
			}
		}
		return errores;
	}

	public List<String> registrarTransferencias(List<Transferencia> detalle,
			long id) throws DomainException {
		List<String> errores = new ArrayList<String>();
		for (Transferencia tra : detalle) {
			try {
				invokeStoreProcedure(REG_TRANSFERENCIAS, id,
						tra.getIdTransferencia());

			} catch (Exception e) {
				throw new DomainException(e);
			}
		}
		return errores;
	}

	@Override
	public void actualizarSolicitudAbono(SolicitudAbono solicitudAbono)
			throws DomainException {
		try {
			invokeStoreProcedure(USP_ACT_SOLIC_ABONO,
					solicitudAbono.getIdSolicitudabono(),
					solicitudAbono.getEstado(),
					solicitudAbono.getUsuarioprobacion());
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public void eliminarSolicitudAbono(SolicitudAbono solicitudAbono)
			throws DomainException {
		invokeStoreProcedure(USP_ELI_SOLIC_ABONO,
				solicitudAbono.getIdSolicitudabono());
	}

	@Override
	public List<SolicitudAbono> listarSolicitudAbono() throws DomainException {

		ResultSet resultSet = invokeStoreProcedureRs(USP_LIS_SOLIC_ABONO,
				new OutParameter(OracleTypes.CURSOR));
		List<SolicitudAbono> solicitudAbonoList = new ArrayList<SolicitudAbono>();
		SolicitudAbono solicitudAbono = new SolicitudAbono();
		try {
			while (resultSet.next()) {
				solicitudAbono = new SolicitudAbono();
				solicitudAbono.setIdSolicitudabono(resultSet
						.getLong("ID_SOLICITUDABONO"));
				solicitudAbono.setEstado(resultSet.getString("ESTADO"));
				solicitudAbono.setNombrearchivo(resultSet
						.getString("NOMBREARCHIVO"));
				solicitudAbono.setFechaaprobacion(resultSet
						.getDate("FECHAAPROBACION"));
				solicitudAbono.setFechaprocesobf(resultSet
						.getDate("FECHAPROCESOBF"));
				Empresa empresa = new Empresa();
				empresa.setNombres(resultSet.getString("EMPRESA"));
				empresa.setRuc(resultSet.getString("RUCEMPRESA"));
				solicitudAbono.setEmpresa(empresa);
				solicitudAbono.setDescripcion(resultSet
						.getString("DESCRIPCION"));
				solicitudAbono.setNroempleados(resultSet
						.getBigDecimal("NROEMPLEADOS"));
				solicitudAbono.setMontototal(resultSet
						.getBigDecimal("MONTOTOTAL"));
				solicitudAbono.setTotalempleados(resultSet
						.getBigDecimal("TOTALEMPLEADOS"));
				solicitudAbono.setTipoabono(resultSet.getString("TIPOABONO"));
				solicitudAbono.setMoneda(resultSet.getString("MONEDA"));
				solicitudAbono.setUsuariocreacion(resultSet
						.getString("USUARIOCREACION"));
				solicitudAbono.setUsuarioprobacion(resultSet
						.getString("USUARIOPROBACION"));

				solicitudAbonoList.add(solicitudAbono);
			}
		} catch (SQLException e) {
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		}
		close(resultSet);
		return solicitudAbonoList;
	}

	@Override
	public List<SolicitudAbono> listarSolicitudAbonoPorEmpresa(
			BigInteger codigoEmpresa) throws DomainException {

		CallableStatement cal = invokeStoreProcedureCallable(
				USP_LIS_SOLIC_ABONO_EMPRESA, codigoEmpresa.longValue() + "",
				new OutParameter(OracleTypes.CURSOR));
		ResultSet resultSet = null;
		List<SolicitudAbono> solicitudAbonoList = new ArrayList<SolicitudAbono>();
		SolicitudAbono solicitudAbono = new SolicitudAbono();
		try {
			resultSet = (ResultSet) cal.getObject(2);
			while (resultSet.next()) {
				solicitudAbono = new SolicitudAbono();
				solicitudAbono.setIdSolicitudabono(resultSet
						.getLong("ID_SOLICITUDABONO"));
				solicitudAbono.setEstado(resultSet.getString("ESTADO"));
				solicitudAbono.setNombrearchivo(resultSet
						.getString("NOMBREARCHIVO"));
				solicitudAbono
						.setFechacarga(resultSet.getDate("FECHACREACION"));
				solicitudAbono.setFechaaprobacion(resultSet
						.getDate("FECHAAPROBACION"));
				solicitudAbono.setFechaprocesobf(resultSet
						.getDate("FECHAPROCESOBF"));
				solicitudAbono.setDescripcion(resultSet
						.getString("DESCRIPCION"));
				solicitudAbono.setNroempleados(resultSet
						.getBigDecimal("NROEMPLEADOS"));
				solicitudAbono.setMontototal(resultSet
						.getBigDecimal("MONTOTOTAL"));
				solicitudAbono.setTotalempleados(resultSet
						.getBigDecimal("TOTALABONADOS"));
				solicitudAbono.setTipoabono(resultSet.getString("TIPOABONO"));
				solicitudAbono.setMoneda(resultSet.getString("MONEDA"));
				solicitudAbono.setUsuariocreacion(resultSet
						.getString("USUARIOCREACION"));
				solicitudAbono.setUsuarioprobacion(resultSet
						.getString("USUARIOPROBACION"));
				solicitudAbono.setSemaforo(resultSet.getString("SEMAFORO"));
				Empresa empresa = new Empresa();
				empresa.setNombres(resultSet.getString("EMPRESA"));
				empresa.setRuc(resultSet.getString("RUCEMPRESA"));
				solicitudAbono.setEmpresa(empresa);
				solicitudAbonoList.add(solicitudAbono);
			}
		} catch (SQLException e) {
			e.printStackTrace();
			throw new DomainException(e);
		} finally {
			try {
				cal.getConnection().close();
				cal.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}

		}
		return solicitudAbonoList;
	}

	@SuppressWarnings("finally")
	@Override
	public List<Abono> listarDetalleSolicitudAbono(BigInteger codigoEmpresa,
			BigInteger codigoSolicitudAbono) throws DomainException {
		ResultSet resultSet = null;
		CallableStatement cal = invokeStoreProcedureCallable(
				USP_LIS_DET_SOLIC_ABONO, codigoEmpresa.longValue() + "",
				codigoSolicitudAbono.longValue() + "", new OutParameter(
						OracleTypes.CURSOR));

		List<Abono> abonoList = new ArrayList<Abono>();
		Abono abono = new Abono();
		try {
			resultSet = (ResultSet) cal.getObject(3);
			while (resultSet.next()) {
				abono = new Abono();
				abono.setIdAbono(resultSet.getLong("ID_ABONO"));
				SolicitudAbono solicitudAbono = new SolicitudAbono();
				solicitudAbono.setIdSolicitudabono(resultSet
						.getLong("ID_SOLICITUDABONO"));

				abono.setSolicitudabono(solicitudAbono);
				abono.setTipodocumento(resultSet.getString("TIPODOCUMENTO"));
				abono.setNrodocumento(resultSet.getString("NRODOCUMENTO"));
				abono.setNombres(resultSet.getString("NOMBRES"));
				abono.setNrocuenta(resultSet.getString("NROCUENTA"));
				abono.setMoneda(resultSet.getString("MONEDA"));
				abono.setMonto(resultSet.getBigDecimal("MONTO"));
				abono.setImporteabono(resultSet.getBigDecimal("IMPORTEABONO"));
				abono.setReferenciaadcional(resultSet
						.getString("REFERENCIAADCIONAL"));
				abono.setNotaabono(resultSet.getString("OBSERVACION"));
				abono.setEstado(resultSet.getString("ESTADO"));

				abonoList.add(abono);
			}
		} catch (SQLException e) {
			e.printStackTrace();
			logger.error(e, e.fillInStackTrace());
			throw new DomainException(e);
		} finally {
			try {
				close(cal.getConnection());
				close(cal);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			return abonoList;
		}

	}

}
